home *** CD-ROM | disk | FTP | other *** search
- /* (C) Copyright 1991 Andrew Plotkin. Permission is
- given to copy and use, as long as this copyright
- notice is retained. */
-
- #include <stdio.h>
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
- #include "spatial.h"
- #include "grey01.bm"
- #include "grey02.bm"
- #include "grey03.bm"
- #include "grey04.bm"
- #include "grey05.bm"
- #include "grey06.bm"
- #include "grey07.bm"
- #include "grey08.bm"
- #include "grey09.bm"
- #include "grey10.bm"
- #include "grey11.bm"
- #include "grey12.bm"
- #include "grey13.bm"
- #include "grey14.bm"
- #include "grey15.bm"
- #include "grey16.bm"
-
- Display *dpy;
- Window win;
- Pixmap backpm, fieldpm;
- GC gcblack, gcwhite, gcinv, gccopy, gcline,
- gcfield, gccubes[16]; /* graphics contexts */
- int scn;
- int scndepth;
- int forcemono = 0;
-
- piecelist pieces[MAXPIECES];
-
- short numpieces;
- short curpiece;
-
- int dispx, dispy; /* size of window */
- int shapex1, shapex2, shapey1, shapey2;
- /* coords of rectangle of backpm that is different from fieldpm */
- int ddispx1, ddispx2, ddispy1, ddispy2;
- /* coords of rectangle of display that is different from fieldpm */
-
- extern void dumppiece(), setup_fieldpm(),
- setup_one_fieldpm(), draw_curpiece();
-
- void xinit() /* using dispx, dispy */
- {
- register int ix;
- XSetWindowAttributes attr;
- XGCValues gcvalues;
- static char dashes[2] = {1, 1};
- Pixmap greypm[16];
- XSizeHints hints;
- Status res;
- XColor col, sccol;
- static unsigned short colvalues[16][3] = {
- {0x0000, 0x0000, 0x0000},
- {0x6000, 0xA000, 0x6000}, /* green grey */
- {0x0000, 0x0000, 0x0000},
- {0x6000, 0x6000, 0xA000}, /* blue grey */
- {0xC000, 0x0000, 0x0000}, /* red */
- {0x0000, 0x0000, 0x0000},
- {0x0000, 0x0000, 0x0000},
- {0xAA00, 0x8000, 0x0000}, /* orange */
- {0x0000, 0x0000, 0x0000},
- {0xC000, 0xC000, 0x0000}, /* yellow */
- {0x0000, 0xC000, 0x0000}, /* green */
- {0x0000, 0x0000, 0xFF00}, /* blue */
- {0x8000, 0x0000, 0xC000}, /* purple */
- {0xFF00, 0x6000, 0x6000}, /* light red */
- {0x8000, 0x8000, 0xFF00}, /* light blue */
- {0xC000, 0xC000, 0xC000} /* light grey */
- };
-
- dpy = XOpenDisplay((char *) NULL);
- if ((Display *) NULL == dpy) {
- fprintf(stderr, "spatial: could not open display.\n");
- exit(-1);
- }
-
- scn = DefaultScreen(dpy);
- scndepth = DefaultDepth(dpy, scn);
-
- win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy),
- 100, 100, dispx, dispy, 1, BlackPixel(dpy, scn),
- WhitePixel(dpy, scn));
-
- hints.min_width = 100;
- hints.min_height = 100;
- hints.width = dispx;
- hints.height = dispy;
- hints.flags = PMinSize | PSize;
- XSetWMNormalHints(dpy, win, &hints);
-
- XStoreName(dpy, win, "Spatial");
-
- attr.event_mask = (KeyPressMask | ExposureMask | StructureNotifyMask);
- XChangeWindowAttributes(dpy, win, CWEventMask, &attr);
-
- XSetWindowBackground(dpy, win, BlackPixel(dpy, scn));
-
- XMapWindow(dpy, win);
-
- gcvalues.foreground = WhitePixel(dpy, scn);
- gcvalues.background = BlackPixel(dpy, scn);
- gcwhite = XCreateGC(dpy, win, GCForeground|GCBackground,
- &gcvalues);
-
- if (forcemono || DefaultDepth(dpy, scn)==1) {
-
- greypm[0] = XCreatePixmapFromBitmapData(dpy, win,
- grey01_bits, grey01_width, grey01_height, 0, 1, 1);
- greypm[1] = XCreatePixmapFromBitmapData(dpy, win,
- grey02_bits, grey02_width, grey02_height, 0, 1, 1);
- greypm[2] = XCreatePixmapFromBitmapData(dpy, win,
- grey03_bits, grey03_width, grey03_height, 0, 1, 1);
- greypm[3] = XCreatePixmapFromBitmapData(dpy, win,
- grey04_bits, grey04_width, grey04_height, 0, 1, 1);
- greypm[4] = XCreatePixmapFromBitmapData(dpy, win,
- grey05_bits, grey05_width, grey05_height, 0, 1, 1);
- greypm[5] = XCreatePixmapFromBitmapData(dpy, win,
- grey06_bits, grey06_width, grey06_height, 0, 1, 1);
- greypm[6] = XCreatePixmapFromBitmapData(dpy, win,
- grey07_bits, grey07_width, grey07_height, 0, 1, 1);
- greypm[7] = XCreatePixmapFromBitmapData(dpy, win,
- grey08_bits, grey08_width, grey08_height, 0, 1, 1);
- greypm[8] = XCreatePixmapFromBitmapData(dpy, win,
- grey09_bits, grey09_width, grey09_height, 0, 1, 1);
- greypm[9] = XCreatePixmapFromBitmapData(dpy, win,
- grey10_bits, grey10_width, grey10_height, 0, 1, 1);
- greypm[10] = XCreatePixmapFromBitmapData(dpy, win,
- grey11_bits, grey11_width, grey11_height, 0, 1, 1);
- greypm[11] = XCreatePixmapFromBitmapData(dpy, win,
- grey12_bits, grey12_width, grey12_height, 0, 1, 1);
- greypm[12] = XCreatePixmapFromBitmapData(dpy, win,
- grey13_bits, grey13_width, grey13_height, 0, 1, 1);
- greypm[13] = XCreatePixmapFromBitmapData(dpy, win,
- grey14_bits, grey14_width, grey14_height, 0, 1, 1);
- greypm[14] = XCreatePixmapFromBitmapData(dpy, win,
- grey15_bits, grey15_width, grey15_height, 0, 1, 1);
- greypm[15] = XCreatePixmapFromBitmapData(dpy, win,
- grey16_bits, grey16_width, grey16_height, 0, 1, 1);
-
- gcvalues.fill_style = FillOpaqueStippled;
- for (ix=0; ix<16; ix++) {
- gcvalues.stipple = greypm[ix];
- gccubes[ix] = XCreateGC(dpy, win,
- GCForeground|GCBackground|GCFillStyle|GCStipple,
- &gcvalues);
- };
- }
- else {
- for (ix=0; ix<16; ix++) {
- col.red = colvalues[ix][0];
- col.green = colvalues[ix][1];
- col.blue = colvalues[ix][2];
- res = XAllocColor(dpy, DefaultColormap(dpy, scn),
- &col);
- if (!res) {
- fprintf(stderr, "spatial: unable to allocate colors\n");
- exit(-1);
- }
- gcvalues.foreground = col.pixel;
- gccubes[ix] = XCreateGC(dpy, win, GCForeground,
- &gcvalues);
- }
-
- }
-
- gcvalues.foreground = WhitePixel(dpy, scn);
- gcvalues.background = BlackPixel(dpy, scn);
-
- gcvalues.line_style = LineOnOffDash;
- gcfield = XCreateGC(dpy, win, GCForeground|GCLineStyle,
- &gcvalues);
-
- XSetDashes(dpy, gcfield, 0, dashes, 2);
- gcvalues.line_width = 2;
- gcline = XCreateGC(dpy, win, GCForeground|GCLineWidth,
- &gcvalues);
-
- gcvalues.foreground = BlackPixel(dpy, scn);
- gcblack = XCreateGC(dpy, win, GCForeground, &gcvalues);
-
- gcvalues.function = GXinvert;
- gcinv = XCreateGC(dpy, win, GCForeground|GCFunction, &gcvalues);
-
- gcvalues.background = WhitePixel(dpy, scn);
- gccopy = XCreateGC(dpy, win, GCForeground|GCBackground, &gcvalues);
- XSetGraphicsExposures(dpy, gccopy, 0);
-
- backpm = XCreatePixmap(dpy, win, dispx, dispy, scndepth);
- fieldpm = XCreatePixmap(dpy, win, dispx, dispy, scndepth);
- }
-
- void setup_fieldpm() /* clear, draw field box and side
- text. Also set shape{x,y}{1,2} to window size */
- {
- XFillRectangle(dpy, fieldpm, gcblack, 0, 0, dispx, dispy);
- XDrawImageString(dpy, fieldpm, gcwhite, 50,
- (int)boardscale+20, "Score: ", 7);
-
- setup_one_fieldpm(fieldpts);
- if (stereo)
- setup_one_fieldpm(fieldpts2);
-
- shapex1 = 0;
- shapex2 = dispx-1;
- shapey1 = 0;
- shapey2 = dispy-1;
- ddispx1 = 0;
- ddispx2 = dispx-1;
- ddispy1 = 0;
- ddispy2 = dispy-1;
- meteroldlev = 0;
- }
-
- void setup_one_fieldpm(fips)
- fieldplist fips;
- {
- register int ix, iy, iz;
-
- for (iz=0; iz<=fieldz; iz++) {
- XDrawLine(dpy, fieldpm, gcfield, fips[0][0][iz].x,
- fips[0][0][iz].y, fips[fieldx][0][iz].x,
- fips[fieldx][0][iz].y);
- XDrawLine(dpy, fieldpm, gcfield,
- fips[fieldx][fieldy][iz].x, fips[fieldx][fieldy][iz].y,
- fips[fieldx][0][iz].x, fips[fieldx][0][iz].y);
- XDrawLine(dpy, fieldpm, gcfield, fips[0][0][iz].x,
- fips[0][0][iz].y, fips[0][fieldy][iz].x, fips[0][fieldy][iz].y);
- XDrawLine(dpy, fieldpm, gcfield,
- fips[fieldx][fieldy][iz].x, fips[fieldx][fieldy][iz].y,
- fips[0][fieldy][iz].x, fips[0][fieldy][iz].y);
- };
- for (ix=0; ix<=fieldx; ix++) {
- XDrawLine(dpy, fieldpm, gcfield, fips[ix][0][0].x,
- fips[ix][0][0].y, fips[ix][0][fieldz].x,
- fips[ix][0][fieldz].y);
- XDrawLine(dpy, fieldpm, gcfield, fips[ix][0][0].x,
- fips[ix][0][0].y, fips[ix][fieldy][0].x, fips[ix][fieldy][0].y);
- XDrawLine(dpy, fieldpm, gcfield,
- fips[ix][fieldy][fieldz].x, fips[ix][fieldy][fieldz].y,
- fips[ix][fieldy][0].x, fips[ix][fieldy][0].y);
- }
- for (iy=1; iy<fieldy; iy++) {
- XDrawLine(dpy, fieldpm, gcfield, fips[0][iy][0].x,
- fips[0][iy][0].y, fips[0][iy][fieldz].x,
- fips[0][iy][fieldz].y);
- XDrawLine(dpy, fieldpm, gcfield, fips[fieldx][iy][0].x,
- fips[fieldx][iy][0].y, fips[0][iy][0].x,
- fips[0][iy][0].y);
- XDrawLine(dpy, fieldpm, gcfield, fips[fieldx][iy][0].x,
- fips[fieldx][iy][0].y, fips[fieldx][iy][fieldz].x,
- fips[fieldx][iy][fieldz].y);
- };
- }
-
- void draw_score(drw)
- Drawable drw;
- {
- static char buf[32];
- register int ix;
- long sc;
-
- if (score==0) {
- XDrawImageString(dpy, drw, gcwhite, 106,
- (int)boardscale+20, "0 ", 10);
- }
- else {
- sc = score;
- ix = 32;
- buf[--ix] = '\0';
- while (sc) {
- buf[--ix] = (sc%10) + '0';
- sc /= 10;
- };
- XDrawImageString(dpy, drw, gcwhite, 106,
- (int)boardscale+20, buf+ix, 31-ix);
- }
- }
-
- void update_meter() /* on fieldpm */
- {
- register int ix;
- int x1, y1, width, heigh;
- GC *gcc;
-
- if (meterlev > meteroldlev) {
- for (ix=meteroldlev; ix<meterlev; ix++) {
- gcc = &(gccubes[colors[ix]]);
- x1 = meterx + metersize*ix;
- y1 = metery;
- width = metersize-1;
- heigh = 20;
- XFillRectangle(dpy, fieldpm, *gcc, x1, y1, width, heigh);
- XDrawRectangle(dpy, fieldpm, gcwhite, x1, y1,
- width, heigh);
- if (stereo) {
- x1 = meterx2 + metersize*ix;
- XFillRectangle(dpy, fieldpm, *gcc, x1, y1,
- width, heigh);
- XDrawRectangle(dpy, fieldpm, gcwhite, x1, y1,
- width, heigh);
- }
- }
- }
- else {
- x1 = meterx + metersize*meterlev + 1;
- y1 = metery;
- width = (meteroldlev - meterlev) * metersize;
- heigh = 20;
- XFillRectangle(dpy, fieldpm, gcblack, x1, y1, width, heigh);
- if (stereo) {
- x1 = meterx2 + metersize*meterlev + 1;
- XFillRectangle(dpy, fieldpm, gcblack, x1, y1,
- width, heigh);
- }
- }
- meteroldlev = meterlev;
- meter_f_b = 1;
- }
-
- void setup_backpm()
- {
- XCopyArea(dpy, fieldpm, backpm, gccopy, shapex1, shapey1,
- shapex2-shapex1+1, shapey2-shapey1+1, shapex1, shapey1);
-
- if (shapey2 > (int)boardscale && shapex1 < 300) {
- draw_score(backpm);
- }
-
- if (meter_f_b) {
- XCopyArea(dpy, fieldpm, backpm, gccopy, meterx,
- metery, metersize*fieldz+1, 21, meterx, metery);
- if (stereo) {
- XCopyArea(dpy, fieldpm, backpm, gccopy, meterx2,
- metery, metersize*fieldz+1, 21, meterx2, metery);
- }
- meter_f_b = 0;
- meter_b_d = 1;
- }
-
- if (curpiece != (-1)) {
- /* draw current piece on backpm, storing
- shape{x,y}{1,2} limits */
- draw_curpiece(backpm);
- }
- }
-
- void back_to_disp(all)
- int all;
- {
- if (all) {
- XCopyArea(dpy, backpm, win, gccopy, 0, 0,
- dispx, dispy, 0, 0);
- }
- else {
- /* copy from backpm to display; area is
- max{shape, ddisp}; */
- if (ddispx1 > shapex1) ddispx1 = shapex1;
- if (ddispy1 > shapey1) ddispy1 = shapey1;
- if (ddispx2 < shapex2) ddispx2 = shapex2;
- if (ddispy2 < shapey2) ddispy2 = shapey2;
- XCopyArea(dpy, backpm, win, gccopy, ddispx1, ddispy1,
- ddispx2-ddispx1+1, ddispy2-ddispy1+1, ddispx1, ddispy1);
-
- if (meter_b_d) {
- XCopyArea(dpy, backpm, win, gccopy, meterx, metery,
- metersize*fieldz+1, 21, meterx, metery);
- if (stereo) {
- XCopyArea(dpy, backpm, win, gccopy, meterx2,
- metery, metersize*fieldz+1, 21, meterx2, metery);
- }
- meter_b_d = 0;
- }
-
- /* set ddisp limits to shape limits; */
- ddispx1 = shapex1;
- ddispy1 = shapey1;
- ddispx2 = shapex2;
- ddispy2 = shapey2;
- }
- }
-
- void loadpieces(flname)
- char *flname;
- {
- register int jx, ix;
- FILE *fl;
- int res;
-
- fl = fopen(flname, "r");
- if (fl==NULL) {
- fprintf(stderr, "spatial: could not open shape file.\n");
- exit(-1);
- };
-
- res=fscanf(fl, "%hd\n", &numpieces);
- if (res!=1) {
- fprintf(stderr, "spatial: error 0 in shape file.\n");
- exit(-1);
- };
-
- for (ix=0; ix<numpieces; ix++) {
- int in1, in2, in3;
- res=fscanf(fl, "%d, %d, %d\n", &in1, &in2, &in3);
- if (res!=3) {
- fprintf(stderr, "spatial: error 1 in shape file.\n");
- exit(-1);
- };
- pieces[ix].numcubes=in1;
- pieces[ix].numverts=in2;
- pieces[ix].numedges=in3;
- pieces[ix].numpoints=in1+in2;
- if (pieces[ix].numpoints>MAXPOINTS || pieces[ix].numedges>MAXEDGES) {
- fprintf(stderr, "spatial: shape %d is too complex.\n", ix);
- exit(-1);
- };
- for (jx=0; jx<pieces[ix].numpoints; jx++) {
- point *p = &(pieces[ix].points[jx]);
- res=fscanf(fl, "%lf, %lf, %lf\n",
- &(p->x), &(p->y), &(p->z));
- if (res!=3) {
- fprintf(stderr, "spatial: error 2 in shape file.\n");
- exit(-1);
- };
- p->w = 1.0;
- };
- pieces[ix].verts =
- &(pieces[ix].points[pieces[ix].numcubes]);
- for (jx=0; jx<pieces[ix].numedges; jx++) {
- res=fscanf(fl, "%d,%d\n", &in1, &in2);
- if (res!=2) {
- fprintf(stderr, "spatial: error 3 in shape file.\n");
- exit(-1);
- };
- pieces[ix].edges[jx].head = in1;
- pieces[ix].edges[jx].tail = in2;
- }
- }
- }
-
- void dumppiece(pnum)
- short pnum;
- {
- piecelist *p = &(pieces[pnum]);
- register int ix;
-
- printf("%d cubes, %d verts, %d edges\n",
- p->numcubes, p->numverts, p->numedges);
- for (ix=0; ix<p->numpoints; ix++) {
- printf("%5.1f, %5.1f, %5.1f, %5.1f\n",
- p->points[ix].x, p->points[ix].y,
- p->points[ix].z, p->points[ix].w);
- }
- for (ix=0; ix<p->numedges; ix++) {
- printf("%d,%d\n", p->edges[ix].head,
- p->edges[ix].tail);
- };
- printf("\n");
- }
-